
// <copyright file="ChunkListTests.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The chunk list tests.
// </summary>

namespace SubhadraSolutions.Sharp.Utils.Tests.Collections.Generic
{
    using System;
    using System.Collections.Generic;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using SubhadraSolutions.Sharp.Utils.Collections.Generic;

    /// <summary>
    /// The chunk list tests.
    /// </summary>
    [TestClass]
    public class ChunkListTests
    {
        #region Fields

        /// <summary>
        /// The random.
        /// </summary>
        private readonly Random _random = new Random();

        #endregion Fields

        #region Public Methods and Operators

        /// <summary>
        /// The add test.
        /// </summary>
        [TestMethod]
        public void AddTest()
        {
            int size = this._random.Next(100000);
            IList<int> list = this.buildList(size);
            int i = 0;
            for (; i < size; i++)
            {
                if (list[i] != i)
                {
                    break;
                }
            }

            Assert.IsTrue(i == size);
        }

        /// <summary>
        /// The index of test.
        /// </summary>
        [TestMethod]
        public void IndexOfTest()
        {
            int size = this._random.Next(100000);
            IList<int> cList = this.buildList(size);
            var list = new List<int>();
            this.populateList(list, size);
            for (int i = 0; i < size; i++)
            {
                if (cList.IndexOf(i) != list.IndexOf(i))
                {
                    Assert.Fail();
                }
            }
        }

        /// <summary>
        /// The remove at test.
        /// </summary>
        [TestMethod]
        public void RemoveAtTest()
        {
            int size = this._random.Next(100000);
            IList<int> cList = this.buildList(size);
            var list = new List<int>();
            this.populateList(list, size);
            while (list.Count > 0)
            {
                int i = this._random.Next(list.Count);
                cList.RemoveAt(i);
                list.RemoveAt(i);
                if (!AreListsEqual(cList, list))
                {
                    Assert.Fail();
                }
            }
        }

        /// <summary>
        /// The remove test.
        /// </summary>
        [TestMethod]
        public void RemoveTest()
        {
            int size = this._random.Next(100000);
            IList<int> cList = this.buildList(size);
            var list = new List<int>();
            this.populateList(list, size);

            // int pendingCount = _random.Next(size - 1) + 1;
            int count = size;
            for (int i = 0; i < count; i++)
            {
                cList.Remove(i);
                list.Remove(i);
                if (!AreListsEqual(cList, list))
                {
                    Assert.Fail();
                }
            }
        }

        #endregion Public Methods and Operators

        #region Methods

        /// <summary>
        /// The build list.
        /// </summary>
        /// <param name="size">
        /// The size.
        /// </param>
        /// <returns>
        /// The <see cref="ChunkList"/>.
        /// </returns>
        private ChunkList<int> buildList(int size)
        {
            var list = new ChunkList<int>();
            this.populateList(list, size);
            Assert.IsTrue(list.Count == size);
            return list;
        }

        /// <summary>
        /// The populate list.
        /// </summary>
        /// <param name="list">
        /// The list.
        /// </param>
        /// <param name="size">
        /// The size.
        /// </param>
        private void populateList(ICollection<int> list, int size)
        {
            for (int i = 0; i < size; i++)
            {
                list.Add(i);
            }
        }

        /// <summary>
        /// Ares the lists equal.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <returns></returns>
        private static bool AreListsEqual<T>(IList<T> x, IList<T> y)
        {
            if (x.Count != y.Count)
            {
                return false;
            }
            
            int count = x.Count;
            for (int i = 0; i < count; i++)
            {
                if (!x[i].Equals(y[i]))
                {
                    return false;
                }
            }

            return true;
        }
        #endregion Methods
    }
}
